package com.zysdev.opengldemo

import android.content.Context
import android.opengl.GLES20
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer

class ScreenFilter {

    //gpu运行程序
    private var program = 0

    //句柄变量  vPosition
    private var vPosition = 0

    //句柄变量  vCoord
    private var vCoord = 0

    //句柄变量  vTexture
    private var vTexture = 0

    //矩阵
    private var vMatrix = 0

    //宽高
    private var mWidth = 0
    private var mHeight = 0
    private var mtx: FloatArray? = null

    //gpu顶点缓冲区 ，顶点坐标缓存区,
    private var vertexBuffer: FloatBuffer? = null

    // 纹理坐标缓冲区
    private var textureBuffer: FloatBuffer? = null

    //GPU中的四个角的世界坐标 ,中心点位0,0
    private var VERTEX = floatArrayOf(
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f, 1.0f,
        1.0f, 1.0f
    )

    //实际纹理的四个角的坐标,这里的纹理不是android的纹理，是其他的纹理坐标系，左下角为0,0
    //android的纹理坐标系是左上角为0，0
    private var TEXTURE = floatArrayOf(
        0.0f, 1.0f,
        1.0f, 1.0f,
        0.0f, 0.0f,
        1.0f, 0.0f
    )

    constructor(context: Context) {
        //将存放要创建的顶点坐标，然后交给gpu中的vPosition
        vertexBuffer =
            ByteBuffer.allocateDirect(4 * 4 * 2).order(ByteOrder.nativeOrder()).asFloatBuffer()
        vertexBuffer?.clear()
        vertexBuffer?.put(VERTEX)

        //将存放要创建的纹理坐标，然后交给gpu中的vCoord
        textureBuffer =
            ByteBuffer.allocateDirect(4 * 4 * 2).order(ByteOrder.nativeOrder()).asFloatBuffer()
        textureBuffer?.clear()
        textureBuffer?.put(TEXTURE)


        //将raw下的顶点着色器vert文件读取为字符串
        val vertexSharder = OpenGLUtils.readRawTextFile(context, R.raw.camera_vert)
        //将raw下的片元着色器frag文件读取为字符串
        val fragSharder = OpenGLUtils.readRawTextFile(context, R.raw.camera_frag)
//        val fragSharder = OpenGLUtils.readRawTextFile(context, R.raw.camera_frag_gary)
//        val fragSharder = OpenGLUtils.readRawTextFile(context, R.raw.camera_frag_bbc)
//        val fragSharder = OpenGLUtils.readRawTextFile(context, R.raw.camera_frag_hot)
//        val fragSharder = OpenGLUtils.readRawTextFile(context, R.raw.camera_frag_rote90)

        //编译顶点着色器和片元着色器的代码，得到GUP程序的句柄
        program = OpenGLUtils.loadProgram(vertexSharder, fragSharder)

        //得到程序中的变量vPosition句柄
        vPosition = GLES20.glGetAttribLocation(program, "vPosition")
        //得到程序中的变量vCoord句柄
        vCoord = GLES20.glGetAttribLocation(program, "vCoord")
        //采样点的坐标
        vTexture=GLES20.glGetUniformLocation(program,"vTexture")
        //变换矩阵， 需要将原本的vCoord（01,11,00,10） 与矩阵相乘
        vMatrix=GLES20.glGetUniformLocation(program,"vMatrix")


    }

    //屏幕发生转变时
    fun setSize(width: Int, height: Int) {
        mWidth = width
        mHeight = height
    }

    //采样矩阵，图层
    fun setTransformMatrixAndDraw(mtx_array:FloatArray,texture:Int){
        this.mtx=mtx_array
        //View 的大小
        GLES20.glViewport(0,0,mWidth,mHeight)
        //使用程序
        GLES20.glUseProgram(program)

        //从索引位0的地方读
        vertexBuffer!!.position(0)

        //     index   指定要修改的通用顶点属性的索引。
        //     size  指定每个通用顶点属性的组件数。
        //     type  指定数组中每个组件的数据类型。
        //     接受符号常量GL_FLOAT  GL_BYTE，GL_UNSIGNED_BYTE，GL_SHORT，GL_UNSIGNED_SHORT或GL_FIXED。 初始值为GL_FLOAT。
        //     normalized    指定在访问定点数据值时是应将其标准化（GL_TRUE）还是直接转换为定点值（GL_FALSE）。
        GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer)
        //生效
        GLES20.glEnableVertexAttribArray(vPosition)



        textureBuffer!!.position(0)
        GLES20.glVertexAttribPointer(vCoord, 2, GLES20.GL_FLOAT, false, 0, textureBuffer)
        //生效
        GLES20.glEnableVertexAttribArray(vCoord)

        //gpu去指定图层读取
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0)

        //生成一个采样器
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture)
        GLES20.glUniform1i(vTexture, 0)
        GLES20.glUniformMatrix4fv(vMatrix, 1, false, mtx, 0)

        //通知渲染，此时才会渲染到屏幕
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4)
    }

}